package com.dwxt.race.service;

import com.dwxt.common.base.BaseResult;
import com.dwxt.common.base.StatusCode;
import com.dwxt.common.util.IDUtils;
import com.dwxt.common.util.PartyUtil;
import com.dwxt.common.util.RegexUtils;
import com.dwxt.race.dao.RaceMapper;
import com.dwxt.race.dao.RaceOrderMapper;
import com.dwxt.race.dao.UserRaceMapper;
import com.dwxt.race.entity.*;
import com.dwxt.race.entity.vo.UserRaceVo;
import com.dwxt.race.service.feign.PayService;
import com.dwxt.race.service.feign.RedisService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * 报名信息管理
 */
@Service
public class UserRaceService {

    @Autowired
    private UserRaceMapper userRaceMapper;
    @Autowired
    private RaceMapper raceMapper;
    @Autowired
    private PayService payService;
    @Autowired
    private RaceOrderMapper raceOrderMapper;
    @Autowired
    private RedisService redisService;

    /**
     * 报名信息提交
     */
    public BaseResult createInfo(UserRaceVo userRaceVo) {
        if (userRaceVo.getRaceId() != null) {
            Race race = raceMapper.selectByPrimaryKey(userRaceVo.getRaceId());
            //报名已满
            if (race.getRegisteredNumber() >= race.getMaxPerson()) {
                return BaseResult.build(StatusCode.RACE_IS_FULL);
            }
            //赛事已禁用
            if (race.getRaceStatus() == 2) {
                return BaseResult.build(StatusCode.RACE_IS_FINISH);
            }
        }
        String currentUserId = PartyUtil.getCurrentUserId();
        userRaceVo.setUserId(currentUserId);
        String certificateNumber = userRaceVo.getCertificateNumber();
        UserRaceExample userRaceExample = new UserRaceExample();
        UserRaceExample.Criteria criteria = userRaceExample.createCriteria();
        //身份证
        if (userRaceVo.getDocumentType() == 1) {
            boolean b = RegexUtils.checkIdCard(certificateNumber);
            if (!b) {
                return BaseResult.build(StatusCode.CERTIFICATION_ISNOT_RIGHT);
            }
            criteria.andCertificateNumberEqualTo(certificateNumber);
        }
        //护照
        if (userRaceVo.getDocumentType() == 2) {
            boolean b = RegexUtils.checkPassport(certificateNumber);
            if (!b) {
                return BaseResult.build(StatusCode.CERTIFICATION_ISNOT_RIGHT);
            }
            criteria.andCertificateNumberEqualTo(certificateNumber);
        }
        //港澳通信证
        if (userRaceVo.getDocumentType() == 3) {
            boolean b = RegexUtils.checkHKcard(certificateNumber);
            if (!b) {
                return BaseResult.build(StatusCode.CERTIFICATION_ISNOT_RIGHT);
            }
            criteria.andCertificateNumberEqualTo(certificateNumber);
        }
        //定位为报名赛事
        if (userRaceVo.getRaceId() != null) {
            List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
            criteria.andRaceIdEqualTo(userRaceVo.getRaceId()).andStatusIn(list);
        }
        List<UserRace> userRaces = userRaceMapper.selectByExample(userRaceExample);
        if (userRaces.size() > 0) {
            return BaseResult.build(StatusCode.INFO_IS_EXIST);
        }

        int insert = userRaceMapper.insertSelective(userRaceVo);
        if (insert > 0) {
            return BaseResult.ok();
        } else {
            return BaseResult.build(StatusCode.FAIL);
        }
    }

    /**
     * 报名信息审核
     */
    public BaseResult confirmInfo(Integer userRaceId, Integer status, String msg) {
        UserRace userRace = userRaceMapper.selectByPrimaryKey(userRaceId);
        Race race = raceMapper.selectByPrimaryKey(userRace.getRaceId());
        if (race.getRaceEndTime().before(new Date())) {
            return BaseResult.build(StatusCode.RACE_IS_FINISH);
        }
        //需要本身为待审核状态-3
        if (userRace.getStatus() == 3) {
            //审核
            userRace.setStatus(status);
            //审核未通过，反馈原因
            if (status == 4) {
                userRace.setReason(msg);
            }
            int i = userRaceMapper.updateByPrimaryKeySelective(userRace);
            if (i > 0) {
                return BaseResult.ok();
            } else {
                return BaseResult.build(StatusCode.FAIL);
            }
        } else {
            return BaseResult.build(StatusCode.RACE_CANNOT_BE_CONFIRM);
        }
    }


    /**
     * 报名支付费用
     *
     * @param payType
     * @return
     */

    @Transactional
    public BaseResult payForRace(Integer userRaceId, Integer payType) {
        String currentUserId = PartyUtil.getCurrentUserId();
        UserRace userRace = userRaceMapper.selectByPrimaryKey(userRaceId);
        Integer raceId = userRace.getRaceId();
        if (raceId != null) {
            Race race = raceMapper.selectByPrimaryKey(raceId);
            String category = "race";
            String name = userRace.getRaceName();
            Integer number = 1;
            Integer integral = race.getIntegral();
            Double realPrice = race.getCost();
            //如果价格为0，直接支付成功
            if (realPrice == 0) {
                userRace.setStatus(1);
            }
            if (payType == 1) {
                BaseResult orderWithZFB = payService.createOrderWithZFB(category, name, number, integral, realPrice);
                HashMap map = (HashMap) orderWithZFB.getData();
                String orderId = map.get("orderId").toString();
                //扣减库存
                raceMapper.updateByOrder(raceId, 1);
                //添加订单号
                userRace.setOrderId(orderId);
                userRaceMapper.updateByPrimaryKey(userRace);
                return orderWithZFB;
            } else if (payType == 2) {
                BaseResult orderWithWX = payService.createOrderWithWX(category, name, number, integral, realPrice);
                HashMap map = (HashMap) orderWithWX.getData();
                String orderId = map.get("orderId").toString();
                raceMapper.updateByOrder(raceId, 1);
                //添加订单号
                userRace.setOrderId(orderId);
                userRaceMapper.updateByPrimaryKey(userRace);
                return orderWithWX;
            }
        }
        return BaseResult.build(StatusCode.FAIL);
    }

    /**
     * 报名支付费用--新版
     *
     * @param payType
     * @return
     */
    @Value("${race.notifyWxUrl}")
    public String notifyWxUrl;
    @Value("${race.notifyZfbUrl}")
    public String notifyZfbUrl;
    @Value("${race.ip}")
    public String ip;

    @Transactional
    public BaseResult payForRaceNew(Integer userRaceId, Integer payType) throws Exception {
        String currentUserId = PartyUtil.getCurrentUserId();
        UserRace userRace = userRaceMapper.selectByPrimaryKey(userRaceId);
        Integer raceId = userRace.getRaceId();
        if (raceId != null) {
            Race race = raceMapper.selectByPrimaryKey(raceId);
            //报名已满
            if (race.getMaxPerson() <= race.getRegisteredNumber()) {
                return BaseResult.build(StatusCode.RACE_IS_FULL);
            }
            Date date = new Date();
            //赛事结束或者禁用
            if (date.after(race.getRaceEndTime()) || race.getRaceStatus() == 2) {
                return BaseResult.build(StatusCode.RACE_IS_FINISH);
            }
            Double realPrice = race.getCost();
            //生成订单Id
            String orderId = "Ra" + IDUtils.genItemId();
            //支付订单创建
            Map<String, String> params = new HashMap<>();
            params.put("price", String.valueOf(realPrice));
            params.put("ip", ip);
            params.put("type", "1");
            params.put("orderId", orderId);

            //如果价格为0，直接支付成功
            if (!(realPrice > 0)) {
                userRace.setStatus(1);
                //扣减库存
                raceMapper.updateByOrder(raceId, 1);
                //添加订单号
                userRace.setOrderId(orderId);
                userRaceMapper.updateByPrimaryKey(userRace);
                RaceOrder raceOrder = new RaceOrder();
                raceOrder.setId("0Ra" + IDUtils.genItemId());
                raceOrder.setRaceid(raceId);
                raceOrder.setUserid(currentUserId);
                raceOrder.setRealprice(realPrice);
                raceOrder.setPaytype(payType);
                raceOrderMapper.insertSelective(raceOrder);
                Map map = new HashMap();
                //map.put("orderString", raceOrder.getId());
                return BaseResult.ok(map);
            }
            if (payType == 1) {
                //支付宝支付
                params.put("notifyUrl", notifyZfbUrl);
                BaseResult result = payService.payWithZFB(params);
                //扣减库存
                raceMapper.updateByOrder(raceId, 1);
                //添加订单号
                userRace.setOrderId(orderId);
                userRaceMapper.updateByPrimaryKey(userRace);
                //订单存入redis
                redisService.set("race_order_zfb" + orderId, orderId, (long) 15 * 60);
                Map map = new HashMap();
                map.put("orderString", result.getData());
                return BaseResult.ok(map);
            } else if (payType == 2) {
                //微信支付
                params.put("notifyUrl", notifyWxUrl);
                BaseResult result = payService.payWithWX(params);
                raceMapper.updateByOrder(raceId, 1);
                userRace.setOrderId(orderId);
                userRaceMapper.updateByPrimaryKey(userRace);
                //订单存入redis
                redisService.set("race_order_wx" + orderId, orderId, (long) 15 * 60);
                return result;
            }
        }
        return BaseResult.build(StatusCode.FAIL);
    }


    //查询我的赛事
    public BaseResult selectRaceListByUserId(Integer pageNum, Integer pageSize, Integer status) {
        PageHelper.startPage(pageNum, pageSize);
        String currentUserId = PartyUtil.getCurrentUserId();
        List<UserRaceVo> userRaces;
        //待参赛
        if (status != null && status == 1) {
            userRaces = userRaceMapper.selectPrepareRace(currentUserId);
        } //历史
        else if (status != null && status == 2) {
            userRaces = userRaceMapper.selectHistoryRace(currentUserId);
        } else {
            userRaces = userRaceMapper.selectUserAndRace(currentUserId);
        }
        PageInfo<UserRaceVo> racePageInfo = new PageInfo<>(userRaces);
        return BaseResult.ok(racePageInfo);
    }

    //赛事退款
    //1：报名成功    0：报名取消    2：待支付   3：待审核   4:审核未通过  5：支付失败 6:超时未支付
    public BaseResult payBack(Integer userRaceId) throws Exception {
        UserRace userRace = userRaceMapper.selectByPrimaryKey(userRaceId);
        RaceOrder raceOrder = raceOrderMapper.selectByPrimaryKey(userRace.getOrderId());
        if (raceOrder != null) {
            BaseResult result;
            //已退款
            if (raceOrder.getStatus() == 3) {
                return BaseResult.build(StatusCode.ORDER_IS_REFUND);
            }
            //支付宝
            if (raceOrder.getPaytype() == 1) {
                result = payService.zbfRefund(raceOrder.getId(), raceOrder.getRealprice());
            } else {
                //微信
                result = payService.wxRefund(raceOrder.getId(), raceOrder.getRealprice());
            }
            if ("SUCCESS".equalsIgnoreCase(result.getData().toString())) {
                //退款成功
                raceOrder.setStatus(3);
                Integer raceId = userRace.getRaceId();
                raceOrderMapper.updateByPrimaryKeySelective(raceOrder);
                //增加库存
                raceMapper.updateByPayBack(raceId, 1);
                return BaseResult.ok();
            } else {
                return BaseResult.build(StatusCode.REFUND_ERROR);
            }
        } else {
//            //退款=>报名取消
//            userRace.setStatus(0);
//            Integer raceId = userRace.getRaceId();
//            //增加库存
//            raceMapper.updateByPayBack(raceId, 1);
//            userRaceMapper.updateByPrimaryKey(userRace);
//            return BaseResult.ok();
            return BaseResult.build(StatusCode.PAYINFO_ISNOT_EXIST);
        }
    }

    //通过赛事页面进入报名详情
    public BaseResult selectListByRaceId(Integer pageNum, Integer pageSize, Integer raceId, String userName, String phone, Integer status) {
        PageHelper.startPage(pageNum, pageSize);
        UserRaceExample userRaceExample = new UserRaceExample();
        UserRaceExample.Criteria criteria = userRaceExample.createCriteria();
        if (raceId != null) {
            criteria.andRaceIdEqualTo(raceId);
        }
        if (StringUtils.isNotBlank(userName)) {
            criteria.andUserNameLike(userName);
        }
        if (StringUtils.isNotBlank(phone)) {
            criteria.andPhoneLike(phone);
        }
        if (status != null) {
            criteria.andStatusEqualTo(status);
        }
        List<UserRace> userRaces = userRaceMapper.selectByExample(userRaceExample);
        PageInfo<UserRace> racePageInfo = new PageInfo<>(userRaces);
        return BaseResult.ok(racePageInfo);
    }

    /**
     * 取消报名
     * 1：报名成功    0：报名取消    2：待支付   3：待审核   4:审核未通过  5：支付失败 6： 超时未支付 7：已退款（视为已报名）
     */
    public BaseResult cancelRace(Integer userRaceId) throws Exception {
        UserRace userRace = userRaceMapper.selectByPrimaryKey(userRaceId);
        Integer status = userRace.getStatus();
        Integer raceId = userRace.getRaceId();
        //已成功报名->取消报名 退款单独退
        if (status == 1) {
//            RaceOrder raceOrder = raceOrderMapper.selectByPrimaryKey(userRace.getOrderId());
//            //1、支付宝   2、微信
//            Integer paytype = raceOrder.getPaytype();
//            BaseResult result;
//            if (paytype == 1) {
//                result = payService.zbfRefund(raceOrder.getId(), raceOrder.getRealprice());
//            } else {
//                result = payService.wxRefund(raceOrder.getId(), raceOrder.getRealprice());
//            }
//            if ("SUCCESS".equalsIgnoreCase(result.getData().toString())) {
            //取消报名
            raceMapper.updateByPayBack(raceId, 1);
            userRace.setStatus(0);
            userRaceMapper.updateByPrimaryKey(userRace);
            //减少已报名人数
            return BaseResult.ok();
//            } else {
//                return BaseResult.build(StatusCode.REFUND_ERROR);
//            }
        } else if (status == 0) {
            return BaseResult.build(StatusCode.RACE_CANCEL_FAIL);
        } else {
            userRace.setStatus(0);
            userRaceMapper.updateByPrimaryKey(userRace);
            return BaseResult.ok();
        }
    }

    public BaseResult selectRaceEnterById(Integer id) {
        return BaseResult.ok(userRaceMapper.selectRaceEnterById(id));
    }

    public BaseResult payForSuccess(String orderId) {
        UserRaceExample userRaceExample = new UserRaceExample();
        userRaceExample.createCriteria().andOrderIdEqualTo(orderId);
        List<UserRace> userRaces = userRaceMapper.selectByExample(userRaceExample);
        if (userRaces.size() == 1) {
            UserRace userRace = userRaces.get(0);
            userRace.setStatus(1);
            userRaceMapper.updateByPrimaryKeySelective(userRace);
            return BaseResult.ok();
        } else {
            return BaseResult.build(StatusCode.INFO_ISNOT_EXIST);
        }
    }

    /**
     * 超时未支付
     *
     * @param orderId
     * @return
     */
    public BaseResult timeoutPayBack(String orderId) {
        UserRaceExample userRaceExample = new UserRaceExample();
        UserRaceExample.Criteria criteria = userRaceExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        List<UserRace> userRaces = userRaceMapper.selectByExample(userRaceExample);
        if (userRaces.size() > 0) {
            UserRace userRace = userRaces.get(0);
            userRace.setStatus(5);
            raceMapper.updateByPayBack(userRace.getRaceId(), 1);
            return BaseResult.ok("订单号：" + orderId + "超时未支付");
        }
        return BaseResult.build(StatusCode.ORDER_IS_REDUCE);
    }
}
